﻿using Common;
using IBLL;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Unmanned_MSUI.Areas.API.Filters;

namespace Unmanned_MSUI.Areas.API.Controllers
{
    /// <summary>
    /// 上传接口
    /// </summary>
    [Area("API")]
   
    public class FileController : Controller
    {
        #region 构造
        private IFileInfoBLL _fileInfoBLL;//文件记录的BLL
        private IHelper _helper;

        public FileController(
            IFileInfoBLL fileInfoBLL
            , IHelper helper
            )
        {
            _fileInfoBLL = fileInfoBLL;
            _helper = helper;
        }
        #endregion

        [APIFilter]//调用Admin的过滤器，如果需要同时判断前台和后台需要登录才能上传可根据情况编写一个过滤器
        #region 公共上传方法
        public IActionResult Upload(IFormFile file)
        {
            ReturnResult res = new ReturnResult();
            try
            {
                //通过Session获取登录人id
                var userId = HttpContext.Request.Cookies["StaffId"];
                if (string.IsNullOrWhiteSpace(userId))
                {
                    res.Msg = "没有登录信息";
                    return Json(res);
                }

                //判断后缀和文件名
                string msg;
                if (!IsFileValid(file, out msg))
                {
                    res.Msg = msg;
                    return Json(res);
                }

                //转换文件为文件流
                Stream stream = file.OpenReadStream();
                string fileId;
                string extension = Path.GetExtension(file.FileName);//获取文件后缀
                //保存到磁盘
                bool isOk = _helper.UpLoad(stream, extension, userId, out fileId, out msg);
                //判断保存磁盘是否成功
                if (!isOk)
                {
                    res.Msg = "保存到磁盘失败！";
                    return Json(res);
                }
                //记录到数据库
                isOk = _fileInfoBLL.CreateFileInfo(fileId, extension, file.Length, userId, out msg);

                res.IsSuccess = isOk;//是否成功
                res.Msg = msg;//返回的消息
                res.Data = fileId;//把文件id返回
                res.Code = isOk ? 200 : res.Code;

                return Json(res);//返回上传结果
            }
            catch (Exception ex)
            {
                res.Msg = "上传文件失败！";
                return Json(res);
            }
        }
        #endregion
        [HttpGet]
        #region 公共下载文件方法
        /// <summary>
        /// 根据id获取文件流（只要是获取上传过的文件都可以用这个方法获取）
        /// </summary>
        /// <param name="id">文件上上传记录的id</param>
        /// <returns></returns>
        public IActionResult Download(string id)
        {
            ReturnResult res = new ReturnResult();
            try
            {
                //根据id获得文件的上传记录
                var file = _fileInfoBLL.GetFileInfoById(id);
                if (file == null)
                {
                    res.Msg = "文件不存在";
                    return Json(res);
                }
                //拼接文件名=文件记录id+文件后缀
                var fileName = file.Id + file.Extension;
                //传递文件名和上传文件人的id，调用下载文件的方法返回文件的文件流
                Stream stream = _helper.DownloadFile(fileName, file.Creator);
                //文件流和文件类型（MIME类型）
                return File(stream, file.Product_Type);
            }
            catch (Exception ex)
            {
                res.Msg = "文件不存在";
                return Json(res);
            }

        }
        #endregion

        #region 判断文件类型是否支持上传和大小是否满足条件
        private static readonly string[] AllowedExtensions = { ".jpg", ".jpeg", ".png", ".gif", ".xls", ".xlsx", ".mp4", ".pdf", ".doc", ".docx" };
        private static readonly long MaxFileSize = 10 * 1024 * 1024; // 10MB

        public bool IsFileValid(IFormFile file, out string msg)
        {
            // 判断上传的文件是否为空
            if (file == null || file.Length == 0)
            {
                msg = "文件为空！";
                return false;
            }

            // 判断文件的大小限制
            if (file.Length > MaxFileSize)
            {
                msg = "文件不能大于10MB";
                return false;
            }

            // 判断文件的后缀
            var fileExtension = Path.GetExtension(file.FileName).ToLower();//把后缀统一转小写
            if (!AllowedExtensions.Contains(fileExtension))
            {
                msg = "该文件类型不可上传！";
                return false;
            }
            msg = "验证通过";
            return true;
        }
        #endregion
    }
}
